package com.ncmmall.mall.controller.business.marketing.gift;

import com.ncmmall.application.business.marketing.GiftApplication;
import com.ncmmall.application.securitys.logs.OperationLogApplication;
import com.feijin.commons.exceptions.IllegalRequestException;
import com.feijin.commons.webs.Webs;
import com.ncmmall.domain.business.goods.Goods;
import com.ncmmall.domain.business.goods.QGoods;
import com.ncmmall.domain.business.goods.channel.GoodsChannel;
import com.ncmmall.domain.business.goods.channel.QGoodsChannel;
import com.ncmmall.domain.business.marketing.gift.GiftActivity;
import com.ncmmall.domain.business.marketing.gift.GiftChannel;
import com.ncmmall.domain.business.marketing.gift.GiftGoods;
import com.ncmmall.domain.business.marketing.gift.GiftScope;
import com.ncmmall.domain.business.marketing.gift.QGiftActivity;
import com.ncmmall.domain.business.marketing.gift.QGiftChannel;
import com.ncmmall.domain.business.marketing.gift.QGiftGoods;
import com.ncmmall.domain.business.marketing.gift.QGiftScope;
import com.ncmmall.domain.business.merchant.MerchantGoodsChannel;
import com.ncmmall.domain.business.merchant.QMerchantGoodsChannel;
import com.ncmmall.mall.controller.securitys.shiro.Securitys;
import com.ncmmall.mall.params.PageParams;
import com.ncmmall.querychannel.QueryPage;
import com.ncmmall.querychannel.QueryPageRequest;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 赠品活动
 *
 * @author linxs
 * @date 2020-01-10 16:32
 */
@Controller
@RequestMapping(value = "/merchant/gift")
public class MerchantGiftController {

    private static final Logger log = LoggerFactory.getLogger(MerchantGiftController.class);

    @Autowired
    private QueryChannelService queryChannelService;

    @Autowired
    private GiftApplication giftApplication;

    @Autowired
    private OperationLogApplication logApplication;

    /**
     * 赠品活动列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    private String list(Model model, PageParams pageParams, GiftActivity giftActivity) {
        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = Maps.newHashMap();
        params.put("id", Securitys.currentUser().getId());
        String hql = builderSQL("select u from GiftActivity u where u.merchant.id = :id and u.status != 6 ", params, giftActivity);
        QueryPage<GiftActivity> page = queryChannelService.findPage(hql, pageRequest.setParams(params), GiftActivity.class);

        model.addAttribute("page", page).addAttribute("params", giftActivity);

        return "merchant/marketing/gift/list";
    }

    /**
     * 添加赠品活动
     */
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    private String create(Model model) {

        GiftActivity giftActivity = new GiftActivity();
        List<GoodsChannel> channels = queryChannelService.findAll(QMerchantGoodsChannel.merchantGoodsChannel.merchant.id.eq(Securitys.currentUser().getId()), MerchantGoodsChannel.class).stream().map(MerchantGoodsChannel::getChannel).collect(Collectors.toList());

        model.addAttribute("_method", "POST").addAttribute("giftActivity", giftActivity).addAttribute("channels", channels);

        return "merchant/marketing/gift/form";
    }

    /**
     * 添加赠品活动
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    private Map<String, Object> create(@RequestHeader("X-Requested-With") String requestWith, GiftActivity giftActivity) {

        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            giftActivity.setMerchant(Securitys.currentUser());
            giftApplication.create(giftActivity);

            return ImmutableMap.of("status", true);

        } catch (Exception e) {

            log.error("[添加赠品活动信息异常]", e);
            return ImmutableMap.of("status", false);

        }
    }

    /**
     * 详情
     */
    @RequestMapping(value = "/{id}/detail", method = RequestMethod.GET)
    private String detail(Model model, @PathVariable("id") long id) {

        GiftActivity giftActivity = queryChannelService.findOne(QGiftActivity.giftActivity.id.eq(id), GiftActivity.class);

        List<GiftGoods> giftGoodses = queryChannelService.findAll(QGiftGoods.giftGoods.gift.eq(giftActivity), GiftGoods.class);
        List<GiftScope> giftScopes = queryChannelService.findAll(QGiftScope.giftScope.gift.eq(giftActivity), GiftScope.class);


        List<GoodsChannel> channels = queryChannelService.findAll(QMerchantGoodsChannel.merchantGoodsChannel.merchant.id.eq(Securitys.currentUser().getId()), MerchantGoodsChannel.class).stream().map(MerchantGoodsChannel::getChannel).collect(Collectors.toList());
        List<String> channelNames = queryChannelService.findAll(QGiftChannel.giftChannel.gift.eq(giftActivity), GiftChannel.class).stream().map(input -> input.getChannel().getName()).collect(Collectors.toList());

        model.addAttribute("giftActivity", giftActivity);
        model.addAttribute("giftGoodses", giftGoodses);
        model.addAttribute("giftScopes", giftScopes);
        model.addAttribute("channelNames", Joiner.on(";").join(channelNames));
        model.addAttribute("_method", "PUT").addAttribute("channels", channels);

        return "merchant/marketing/gift/detail";

    }

    /**
     * 编辑赠品活动
     */
    @RequestMapping(value = "/{id}/modify", method = RequestMethod.GET)
    public String create(Model model, @PathVariable("id") long id) {

        GiftActivity giftActivity = queryChannelService.findOne(QGiftActivity.giftActivity.id.eq(id), GiftActivity.class);

        List<GiftGoods> giftGoodses = queryChannelService.findAll(QGiftGoods.giftGoods.gift.eq(giftActivity), GiftGoods.class);
        List<GiftScope> giftScopes = queryChannelService.findAll(QGiftScope.giftScope.gift.eq(giftActivity), GiftScope.class);

        List<GoodsChannel> channels = queryChannelService.findAll(QMerchantGoodsChannel.merchantGoodsChannel.merchant.id.eq(Securitys.currentUser().getId()), MerchantGoodsChannel.class).stream().map(MerchantGoodsChannel::getChannel).collect(Collectors.toList());
        List<String> channelNames = queryChannelService.findAll(QGiftChannel.giftChannel.gift.eq(giftActivity), GiftChannel.class).stream().map(input -> input.getChannel().getName()).collect(Collectors.toList());

        model.addAttribute("giftActivity", giftActivity);
        model.addAttribute("giftGoodses", giftGoodses);
        model.addAttribute("giftScopes", giftScopes);
        model.addAttribute("channelNames", Joiner.on(";").join(channelNames));
        model.addAttribute("_method", "PUT").addAttribute("channels", channels);

        return "merchant/marketing/gift/form";
    }


    /**
     * 编辑赠品活动
     */
    @RequestMapping(value = "/{id}/modify", method = RequestMethod.PUT)
    @ResponseBody
    public Map<String, Object> modify(HttpServletRequest request, GiftActivity giftActivity) {
        try {
            if (!Webs.isAjaxRequest(request)) {
                throw new IllegalArgumentException("request must be ajax");
            }

            giftApplication.modify(giftActivity);
            return ImmutableMap.of("status", true, "message", "编辑成功");

        } catch (Exception e) {
            log.error("赠品活动编辑异常", e);
            return ImmutableMap.of("status", false, "message", "编辑异常");
        }
    }

    /**
     * 提交审核
     */
    @RequestMapping(value = "/applyProcess", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> applyProcess(HttpServletRequest request, long id) {
        try {

            if (!Webs.isAjaxRequest(request)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            GiftActivity giftActivity = queryChannelService.findOne(QGiftActivity.giftActivity.id.eq(id), GiftActivity.class);

            giftApplication.applyProcess(giftActivity);
            logApplication.eventOfMerchant(Securitys.currentUser(), "提交赠品活动审核", Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[提交赠品活动审核异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 上架
     */
    @RequestMapping(value = "/putaway", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> putaway(HttpServletRequest request, long id) {
        try {

            if (!Webs.isAjaxRequest(request)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            GiftActivity giftActivity = queryChannelService.findOne(QGiftActivity.giftActivity.id.eq(id), GiftActivity.class);

            giftApplication.putaway(giftActivity);
            logApplication.eventOfMerchant(Securitys.currentUser(), "赠品活动上架", Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[赠品活动上架异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 下架
     */
    @RequestMapping(value = "/soldout", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> soldout(HttpServletRequest request, long id) {
        try {

            if (!Webs.isAjaxRequest(request)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            GiftActivity giftActivity = queryChannelService.findOne(QGiftActivity.giftActivity.id.eq(id), GiftActivity.class);

            giftApplication.soldout(giftActivity);
            logApplication.eventOfMerchant(Securitys.currentUser(), "赠品活动下架", Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[赠品活动下架异常]", e);
            return ImmutableMap.of("status", false);
        }
    }


    /**
     * 删除
     */
    @RequestMapping(value = "/remove", method = RequestMethod.DELETE)
    @ResponseBody
    private Map<String, Object> remove(HttpServletRequest request, long id) {
        try {

            if (!Webs.isAjaxRequest(request)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            GiftActivity giftActivity = queryChannelService.findOne(QGiftActivity.giftActivity.id.eq(id), GiftActivity.class);

            giftApplication.remove(giftActivity);
            logApplication.eventOfMerchant(Securitys.currentUser(), "删除赠品活动", Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {

            log.error("[删除赠品活动异常]", e);
            return ImmutableMap.of("status", false);

        }
    }


    /**
     * 选择赠品
     */
    @RequestMapping(value = "/chooseGiftGoods", method = RequestMethod.GET)
    private String chooseGiftGoods(Model model, PageParams pageParams, Goods coupon) {
        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = Maps.newHashMap();
        params.put("id", Securitys.currentUser().getId());
        String hql = builderGiftGoodsSQL("select u from Goods u where u.merchant.id = :id and u.status = 3 and u.marketingType = 0 and u.isIssuingType = 0 ", params, coupon);
        QueryPage<Goods> page = queryChannelService.findPage(hql, pageRequest.setParams(params), Goods.class);

        model.addAttribute("page", page)
                .addAttribute("params", coupon)
                .addAttribute("channels", queryChannelService.findAll("select c from GoodsChannel c where c.deleteStatus = 0 and  c.level = 1 and c.status = 1 ", GoodsChannel.class));

        return "merchant/marketing/gift/chooseGiftGoods";
    }


    /**
     * 选择适用商品
     */
    @RequestMapping(value = "/chooseScopeGoodses", method = RequestMethod.GET)
    private String chooseScopeGoodses(Model model, PageParams pageParams, Goods coupon) {
        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = Maps.newHashMap();
        params.put("id", Securitys.currentUser().getId());
        String hql = builderGiftGoodsSQL("select u from Goods u where u.merchant.id = :id and u.status = 3 and u.isIssuingType = 0 ", params, coupon);
        QueryPage<Goods> page = queryChannelService.findPage(hql, pageRequest.setParams(params), Goods.class);

        model.addAttribute("page", page)
                .addAttribute("params", coupon)
                .addAttribute("channels", queryChannelService.findAll("select c from GoodsChannel c where c.deleteStatus = 0 and  c.level = 1 and c.status = 1 ", GoodsChannel.class));


        return "merchant/marketing/gift/chooseScopeGoodses";
    }

    /**
     * 查询商品
     *
     * @param ids 商品id
     */
    @RequestMapping(value = "/queryGoodses", method = RequestMethod.GET)
    @ResponseBody
    private Map<String, Object> queryGoodses(@RequestParam("ids") String ids) {

        if (StringUtils.isBlank(ids)) {
            return ImmutableMap.of("status", true, "goodses", Collections.emptyList());
        }

        List<Long> longIds = Splitter.on("-").omitEmptyStrings().trimResults().splitToList(ids).stream().map(Long::valueOf).collect(Collectors.toList());
        List<Goods> goodses = queryChannelService.findAll(QGoods.goods.id.in(longIds), Goods.class);

        return ImmutableMap.of("status", true, "goodses", goodses);

    }

    private String builderGiftGoodsSQL(String sql, Map<String, Object> params, Goods goods) {
        if (goods.getIsSupplier() > 0) {
            sql += " and u.isSupplier = 1 ";
        } else {
            sql += " and u.isSupplier = 0 ";
        }

        if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getId() > 0) {
            goods.setGoodsChannel(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getId());

        } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent().getId() > 0) {
            goods.getGoodsChannel().setParent(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getParent().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.parent.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getParent().getId());

        } else if (null != goods.getGoodsChannel() && goods.getGoodsChannel().getParent().getParent().getId() > 0) {
            goods.getGoodsChannel().getParent().setParent(queryChannelService.findOne(QGoodsChannel.goodsChannel.id.eq(goods.getGoodsChannel().getParent().getParent().getId()), GoodsChannel.class));

            sql += " and u.goodsChannel.parent.parent.id = :cid ";
            params.put("cid", goods.getGoodsChannel().getParent().getParent().getId());
        }

        if (goods.getMerchant() != null && goods.getMerchant().getId() > 0) {
            sql += " and u.merchant.id = :merchantId ";
            params.put("merchantId", goods.getMerchant().getId());
        }

        if (goods.getStatus() > 0) {
            sql += " and u.status = :status ";
            params.put("status", goods.getStatus());
        } else {
            sql += " and u.status in (3,6) ";
        }

        if (!Strings.isNullOrEmpty(goods.getGoodsNo())) {
            sql += " and u.goodsNo like :goodsno ";
            params.put("goodsno", "%" + goods.getGoodsNo() + "%");
        }

        if (!Strings.isNullOrEmpty(goods.getName())) {
            sql += " and u.name like :name ";
            params.put("name", "%" + goods.getName() + "%");
        }


        if (!Strings.isNullOrEmpty(goods.getOrderByCreateTime())) {
            sql += " order by u.createTime " + goods.getOrderByCreateTime();
        } else if (!Strings.isNullOrEmpty(goods.getOrderByPrice())) {
            sql += " order by u.defaultPrice " + goods.getOrderByPrice();
        } else if (!Strings.isNullOrEmpty(goods.getOrderByStore())) {
            sql += " order by u.store " + goods.getOrderByStore();
        } else if (!Strings.isNullOrEmpty(goods.getOrderBySalesVolume())) {
            sql += " order by u.salesVolume " + goods.getOrderBySalesVolume();
        } else {
            sql += " order by u.createTime desc ";
        }

        return sql;
    }

    /**
     * 条件筛选
     */
    private String builderSQL(String hql, Map<String, Object> params, GiftActivity giftActivity) {

        if (giftActivity.getIsValidity() > 0) {
            hql += " and u.isValidity = :validity ";
            params.put("validity", giftActivity.getIsValidity());
        }

        if (!Strings.isNullOrEmpty(giftActivity.getGiftNames())) {
            hql += " and u.name like :name ";
            params.put("name", "%" + giftActivity.getGiftNames() + "%");
        }

        return hql + " order by u.createTime desc";
    }

}
